//
// Created by Crestimes on 24-6-8.
//

#include "BaseAlgorithm.h"

#include <iomanip>
#include <iostream>

void BaseAlgorithm::start(const bool& log) {
    if (log) LINE;
    cout << "--------------- " << algorithmName << " ------------------" << endl;
    for (int i = 0; i < pageList.size(); i++) {
        int page = pageList[i];
        if (log) LINE;
        if (log) cout << "Try to insert page: " << page << endl;
        // 判断是否缺页
        bool isLimit = true;
        for (const auto& p : pagesNow) {
            if (p == page) isLimit = false;
        }
        if (isLimit) {
            // 缺页
            limitIndex.insert(i);
            if (log) cout << "Limit! Total limit times now: " << limitIndex.size() << endl;
            if (pagesNow.size() < maxSize) {
                // 还可以插入
                pagesNow.push_back(page);
                if (log) cout << "Insert page: " << page << endl;
            }
            else {
                // ------------------------------------------------------------------------
                // 在缺页且需要更换页面时各算法有不同的操作
                int out; // out 用引用传入可以获取不同算法的不同置换页号
                doSomethingWhenLimit(i, out);
                // ------------------------------------------------------------------------
                if (log) cout << "Exchange page: " << out << " ----> " << page << endl;
            }
        }
        else {
            if (log) cout << "No problem~" << endl;
        }
        showList.push_back(pagesNow);
    }
    show();
}

void BaseAlgorithm::show() {
    cout << algorithmName << " process:" << endl;
    for (int i = 0; i < showList.size(); i++) {
        cout << "[" << i << "] \tinput: " << pageList[i] << " \t\t";
        for (const int page : showList[i]) {
            cout << " " << page;
        }
        for (int j = 0; j < maxSize - showList[i].size(); j++) cout << "  "; // 补空对齐
        if (limitIndex.count(i)) cout << "\t\t+";
        else cout << "\t\t";
        cout << endl;
    }
    LINE;
    cout << "OutPageList:";
    for (const int page : outPageList) {
        cout << " " << page;
    }
    cout << endl << "Limit ratio: " << fixed << setprecision(3)
        << static_cast<float>(limitIndex.size()) / static_cast<float>(pageList.size()) << endl;
    LINE;
}
